// 购物车状态
// 购物车的字段

import {
    getNewCartGoods,
    mergeLocalCart,
    getCartList,
    insertCart,
    deleteCart,
    updateCart,
    checkAllCart
} from '@/api/cart'

// 本地：id skuId name picture price nowPrice count attrsText selected stock isEffective
export default {
    namespaced: true,
    state: () => {
        return {
            list: []
        }
    },
    getters: {
        // 有效的购物车列表数据
        validList(state) {
            return state.list.filter(v => v.isEffective && v.stock > 0)
        },
        // 有效的购物车商品件数
        validCount(state, getters) {
            return getters.validList.reduce((p, c) => p + c.count, 0)
        },
        // 有效的购物车商品的总金额
        validTotalFee(state, getters) {
            return getters.validList.reduce((p, c) => p + c.nowPrice * c.count, 0).toFixed(2)
        },
        // 无效的商品数据
        invalidList(state) {
            return state.list.filter(v => v.isEffective === false || v.stock < 0)
        },
        // 选中的有效的商品列表
        selectedList(state, getters) {
            return getters.validList.filter(v => v.selected)
        },
        // 选中的有效商品件数
        selectedTotal(state, getters) {
            return getters.selectedList.reduce((p, c) => p + c.count, 0)
        },
        // 选中的有效商品总金额
        selectedAmount(state, getters) {
            return getters.selectedList.reduce((p, c) => p + c.nowPrice * c.count, 0).toFixed(2)
        },
        // 有效的是否全选
        isCheckAll(state, getters) {
            return getters.validList.length === getters.selectedList.length && getters.selectedList.length !== 0
        }

    },
    mutations: {
        // 5、清空或者存储购物车数据,如果list的值是空数组，那么就是清空本地的购物车数据，如果是一个数组，那么就是设置本地的购物车数据
        setCartList(state, list) {
            state.list = list
        },
        // 4.全选和全不选
        checkAll(state, checkAllStatus) {
            state.list.forEach(item => {
                if (item.isEffective && item.stock > 0) {
                    item.selected = checkAllStatus
                }
            })
        },
        // 1. 添加购物车：
        // 区分情况：1.新添加的sku商品;2.原来在列表中有，只需要进行数量上添加
        insertCart(state, payload) {
            // 查询出当前待添加的数据在列表中有没有
            const sameIndex = state.list.findIndex(item => item.skuId === payload.skuId)
            if (sameIndex !== -1) {
                // 旧商品
                state.list[sameIndex].count = state.list[sameIndex].count + payload.count
            } else {
                // 新商品
                state.list.unshift(payload)
            }
        },
        // 2.修改购物车信息（价格、库存），将来还有可能在购物车页面修改商品的数量和选中状态等
        updateCart(state, goods) {
            const updateGoods = state.list.find(v => v.skuId === goods.skuId)

            // 将来修改的商品属性不止一个，所以需要对可能修改的属性做遍历
            for (const key in goods) {
                // 传递过来修改的数据不能为空
                if (goods[key] !== null || goods[key] !== '' || goods[key] !== undefined) {
                    updateGoods[key] = goods[key]
                }
            }
        },
        // 3.  删除购物车商品
        deleteCart(state, skuId) {
            const index = state.list.findIndex(item => item.skuId === skuId)
            state.list.splice(index, 1)
        }
    },
    actions: {
        // 7. 登录后合并购物车数据
        async mergeLocalCart(ctx) {
            // 方式一：forEach
            const skus = []
            ctx.getters.validList.forEach(item => {
                skus.push({
                    skuId: item.skuId,
                    selected: item.selected,
                    count: item.count
                })
            })

            // 方式二： map
            /*  const skus = ctx.getters.validList.map(({
                 skuId,
                 selected,
                 count
             }) => {
                 return {
                     skuId,
                     selected,
                     count
                 }
             }) */

            // 合并
            await mergeLocalCart(skus)

            // 清空本地购物车数据
            ctx.commit('setCartList', [])
        },
        // 6.修改sku
        updateSku(ctx, payload) {
            return new Promise((resolve, reject) => {
                if (ctx.rootState.user.profile.token) {
                    // 登录
                    const {
                        skuId: id, // 旧的skuId
                        newSku
                    } = payload
                    // 先获取旧值
                    const oldGoods = ctx.getters.validList.find(item => item.skuId === id)
                        // 先删除旧的skuId数据
                    deleteCart([id]).then(() => {
                        // 再把新的添加进去，再重新查询
                        return insertCart({
                            skuId: newSku.skuId,
                            count: oldGoods.count
                        })
                    }).then(() => {
                        return getCartList()
                    }).then(data => {
                        ctx.commit('setCartList', data.result)
                    })
                } else {
                    const {
                        skuId: id, // 旧的skuId
                        newSku
                    } = payload
                    // 先获取旧值
                    const oldGoods = ctx.getters.validList.find(item => item.skuId === id)

                    // 先删除原来的skuId对应的数据
                    ctx.commit('deleteCart', id)

                    // 需要组装好数据
                    const {
                        skuId,
                        price,
                        price: nowPrice,
                        specsText: attrsText,
                        inventory: stock
                    } = newSku
                    const sku = {
                        ...oldGoods,
                        skuId,
                        price,
                        nowPrice,
                        attrsText,
                        stock
                    }

                    // 再重新添加当前选择好的sku数据
                    ctx.commit('insertCart', sku)

                    resolve()
                }
            })
        },
        // 5.全选和全不选
        checkAll(ctx, payload) {
            return new Promise((resolve, reject) => {
                if (ctx.rootState.user.profile.token) {
                    // 登录
                    // 获取所有有效购物车商品的集合
                    const skuIds = ctx.getters.validList.map(({
                        skuId
                    }) => {
                        return skuId
                    })
                    checkAllCart({
                        selected: payload,
                        ids: skuIds
                    }).then(() => {
                        // 从服务器查询最新的购物车数据
                        return getCartList()
                    }).then(data => {
                        ctx.commit('setCartList', data.result)
                    })
                } else {
                    // 未登录
                    ctx.commit('checkAll', payload)

                    // 成功的处理
                    resolve()
                }
            })
        },

        // 4.修改购物车商品的选中状态
        updateCart(ctx, payload) {
            return new Promise((resolve, reject) => {
                if (ctx.rootState.user.profile.token) {
                    // 登录
                    const {
                        skuId,
                        selected,
                        count
                    } = payload
                    updateCart({
                        skuId,
                        selected,
                        count
                    }).then(() => {
                        // 从服务器查询最新的购物车数据
                        return getCartList()
                    }).then(data => {
                        ctx.commit('setCartList', data.result)
                    })
                } else {
                    // 未登录
                    ctx.commit('updateCart', payload)

                    // 成功的处理
                    resolve()
                }
            })
        },
        // 1.添加购物车
        insertCart(ctx, payload) {
            // 返回Promise兼容本地和服务器api的操作
            return new Promise((resolve, reject) => {
                if (ctx.rootState.user.profile.token) {
                    // 登录调api
                    insertCart({
                        skuId: payload.skuId,
                        count: payload.count
                    }).then(() => {
                        // 从服务器查询最新的购物车数据
                        return getCartList()
                    }).then(data => {
                        ctx.commit('setCartList', data.result)
                    })
                } else {
                    // 未登录
                    ctx.commit('insertCart', payload)

                    // 成功的处理
                    resolve()
                }
            })
        },
        // 2.每次查看购物车数据时，需要调获取购物车商品最新信息的api,然后更新购物车的数据
        findCurrentCartList(ctx, payload) {
            return new Promise((resolve, reject) => {
                if (ctx.rootState.user.profile.token) {
                    // 登录后，重新从服务器拉取该登录用户的所有的购物车数据，并本地持久化
                    getCartList().then(data => {
                        ctx.commit('setCartList', data.result)
                    })
                } else {
                    // 未登录
                    // 问题：如果有多个skuid，那么就需要循环更新，那么就可能会出现某次更新不成功的问题
                    const promiseArr = ctx.state.list.map(item => {
                        return getNewCartGoods(item.skuId)
                    })

                    // 通过Promise.all()一次性执行多个异步操作,dataArr就是所有异步操作的返回值的数组
                    Promise.all(promiseArr).then(dataArr => {
                        dataArr.forEach((item, i) => {
                            ctx.commit('updateCart', {
                                skuId: ctx.state.list[i].skuId,
                                ...item.result
                            })
                        })
                        resolve()
                    }).catch(err => {
                        reject(err)
                    })
                }
            })
        },
        // 3.删除购物车
        deleteCart(ctx, skuId) {
            return new Promise((resolve, reject) => {
                if (ctx.rootState.user.profile.token) {
                    // 登录
                    deleteCart([skuId]).then(() => {
                        // 从服务器查询最新的购物车数据
                        return getCartList()
                    }).then(data => {
                        ctx.commit('setCartList', data.result)
                    })
                } else {
                    // 本地
                    ctx.commit('deleteCart', skuId)
                    resolve()
                }
            })
        },
        // 6.批量删除购物车数据
        batchDeleteCart(ctx, isClear) {
            return new Promise((resolve, reject) => {
                if (ctx.rootState.user.profile.token) {
                    // 登录
                    // 获取所有选中的skuIds
                    const skuIds = ctx.getters.selectedList.map(({
                        skuId
                    }) => {
                        return skuId
                    })

                    deleteCart(skuIds).then(() => {
                        // 从服务器查询最新的购物车数据
                        return getCartList()
                    }).then(data => {
                        ctx.commit('setCartList', data.result)
                    })
                } else {
                    // 本地
                    // 1. 获取选中商品列表，进行遍历调用deleteCart mutataions函数
                    const cartList = isClear ? ctx.getters.invalidList : ctx.getters.selectedList
                    cartList.forEach(item => {
                        ctx.commit('deleteCart', item.skuId)
                    })
                    resolve()
                }
            })
        }
    }
}